/*
 * Copyright (c) 2025 Huawei Device, Inc. Ltd. and <马弓手>.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "AccelListener.h"
#include "CordovaViewController.h"
#include "cJSON.h"

REGISTER_PLUGIN_CLASS(AccelListener)
bool AccelListener::execute(const string&  action, cJSON* args, CallbackContext cbc)
{
    if(action == "start") {
        m_cbc = cbc;
        if(CreateSubscribeInfo()) {
            PluginResult pluginResult(PluginResult::NO_RESULT, "");
            pluginResult.setKeepCallback(true);
            cbc.sendPluginResult(pluginResult);
            m_isStatus = true;
        }
    }
    
    if(action == "stop") {
        if(m_isStatus) {
            DestroySubscribeInfo();
            PluginResult pluginResult(PluginResult::NO_RESULT, "");
            cbc.sendPluginResult(pluginResult);
            m_isStatus = false;
        }
    }
    return true;
}

bool AccelListener::CreateSubscribeInfo()
{
    m_user = OH_Sensor_CreateSubscriber();                                         // 创建一个Sensor_Subscriber实例。
    int32_t ret = OH_SensorSubscriber_SetCallback(m_user, AccelListener::onRevice); // 设置一个回调函数来报告传感器数据。
    if (ret != SENSOR_SUCCESS) {
        return false;
    }

    Sensor_Type SENSOR_ID  = SENSOR_TYPE_ACCELEROMETER;
    m_id = OH_Sensor_CreateSubscriptionId(); // 创建一个Sensor_SubscriptionId实例。
    ret = OH_SensorSubscriptionId_SetType(m_id, SENSOR_ID);         // 设置传感器类型。
    if (ret != SENSOR_SUCCESS) {
        return false;
    }

    int64_t SENSOR_SAMPLE_PERIOD = m_nFrequency*1000*1000;//ns
    m_attr = OH_Sensor_CreateSubscriptionAttribute();     // 创建Sensor_SubscriptionAttribute实例。
    ret = OH_SensorSubscriptionAttribute_SetSamplingInterval(m_attr, SENSOR_SAMPLE_PERIOD); // 设置传感器数据报告间隔。
    if (ret != SENSOR_SUCCESS) {
        return false;
    }

    ret = OH_Sensor_Subscribe(m_id, m_attr, m_user); // 订阅传感器数据。
    if (ret != SENSOR_SUCCESS) {
        return false;
    }
    return true;
}

void AccelListener::DestroySubscribeInfo()
{
    int32_t ret = OH_Sensor_Unsubscribe(m_id, m_user); // 取消订阅传感器数据。
    if (ret != SENSOR_SUCCESS) {
        return;
    }
    if (m_id != nullptr) {
        OH_Sensor_DestroySubscriptionId(m_id); // 销毁Sensor_SubscriptionId实例并回收内存。
        m_id = nullptr;
    }
    if (m_attr != nullptr) {
        OH_Sensor_DestroySubscriptionAttribute(m_attr); // 销毁Sensor_SubscriptionAttribute实例并回收内存。
        m_attr = nullptr;
    }
    if (m_user != nullptr) {
        OH_Sensor_DestroySubscriber(m_user); // 销毁Sensor_Subscriber实例并回收内存。
        m_user = nullptr;
    }
    return;
}

void AccelListener::onRevice(Sensor_Event *event)
{
    AccelListener* pAccelListener = (AccelListener*)((CordovaViewController*)Application::g_cordovaViewController)->getPluginManager()->getPlugin("Accelerometer");
    pAccelListener->updateAccelInfo(event);
}

void AccelListener::updateAccelInfo(Sensor_Event *event)
{
    if (event == nullptr) {
        return;
    }
    int64_t timestamp = -1;
    int32_t ret = OH_SensorEvent_GetTimestamp(event, &timestamp); // 获取传感器数据的时间戳。
    if (ret != SENSOR_SUCCESS) {
        return;
    }
    Sensor_Type sensorType;
    ret = OH_SensorEvent_GetType(event, &sensorType); // 获取传感器类型。
    if (ret != SENSOR_SUCCESS) {
        return;
    }
    Sensor_Accuracy accuracy = SENSOR_ACCURACY_UNRELIABLE;
    ret = OH_SensorEvent_GetAccuracy(event, &accuracy); // 获取传感器数据的精度。
    if (ret != SENSOR_SUCCESS) {
        return;
    }
    float *data = nullptr;
    uint32_t length = 0;
    ret = OH_SensorEvent_GetData(event, &data, &length); // 获取传感器数据。
    if (ret != SENSOR_SUCCESS) {
        return;
    }
    if (data == nullptr) {
        return;
    }
    OH_LOG_Print(LOG_APP, LOG_INFO, 0xff00, "AccelListener","sensorType:%{public}d, dataLen:%{public}d, accuracy:%{public}d", sensorType, length, accuracy);
    float x = 0;
    float y = 0;
    float z = 0;
    
    for (uint32_t i = 0; i < length; ++i) {
        if(i == 0) {
            x = data[i];
        } 
        if(i == 1) {
            y = data[i];
        }
        if(i == 2) {
            z = data[i];
        }
        
        OH_LOG_Print(LOG_APP, LOG_INFO, 0xff00, "AccelListener", "data[%{public}d]:%{public}f", i, data[i]);
    }
    
    cJSON* pJson = cJSON_CreateObject();
    cJSON_AddNumberToObject(pJson, "timestamp", timestamp);
    cJSON_AddNumberToObject(pJson, "x", x);
    cJSON_AddNumberToObject(pJson, "y", y);
    cJSON_AddNumberToObject(pJson, "z", z);
    PluginResult pluginResult(PluginResult::OK, pJson);
    pluginResult.setKeepCallback(true);
    m_cbc.sendPluginResult(pluginResult);
    cJSON_Delete(pJson);
}
